package com.ymttest.database.mongo.converter;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.List;

import com.ymttest.utils.DataUtil;

public class ConvertUtils {
	private static Method getMethod(String modify, Class<?> cls, String fieldName, Class<?>... classes) {
		Method method = null;
		try {
			method = cls.getMethod(modify + DataUtil.toUpperCaseFirstOne(fieldName), classes);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		return method;
	}

	private static Object invokeMethod(Method method, Object obj, Object... args) {
		Object object = null;
		try {
			object = method.invoke(obj, args);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return object;
	}

	private static boolean filterBigDecimal(String fieldType) {
		return fieldType.startsWith("com.ymttest") || "java.util.List".equals(fieldType)
						|| "java.math.BigDecimal".equals(fieldType);
	}

	/**
	 * 由于数据库同步到mongo中的订单数据的金额是乘100的,所以从mongo中查出的数据转换为BigDecimal类型的数据需要除100
	 * @param o
	 */
	public static void convertBigDecimal(Object o) {
		Class<? extends Object> cls = o.getClass();
		Field[] fields = cls.getDeclaredFields();
		for (Field field : fields) {
			String fieldType = field.getType().getName();
			String fieldName = field.getName();
			if (filterBigDecimal(fieldType)) {
				Method get = getMethod("get", cls, fieldName);
				Object before = invokeMethod(get, o);
				if (null != before) {
					if ("java.math.BigDecimal".equals(fieldType)) {
						Method set = getMethod("set", cls, fieldName, BigDecimal.class);
						invokeMethod(set, o, DataUtil.BigDecimall.GetValueOrDefault(before).divide(new BigDecimal(100))
										.setScale(2));
					} else if ("java.util.List".equals(fieldType)) {
						for (Object object : (List<?>) before) {
							convertBigDecimal(object);
						}
					} else {
						convertBigDecimal(before);
					}
				}

			}
		}
	}
}
